package com.service.scheduling.task;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import com.service.dao.enums.CoinsEnum;
import com.service.dao.enums.MemberJAType;
import com.service.dao.enums.RwRecordEnum;
import com.service.dao.enums.WalletEnums;
import com.service.dao.model.MemberStore;
import com.service.dao.model.RwRecord;
import com.service.scheduling.dto.MemberStoreChange;
import com.service.scheduling.service.MemberStoreService;
import com.service.scheduling.service.RwRecordService;
import com.service.scheduling.support.MemberStoreLockUtils;
import com.service.scheduling.utils.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 自动充值执行任务
 */
@Slf4j
@Component
public class RechargeTask {

    @Autowired
    private RwRecordService rwRecordService;
    @Autowired
    private MemberStoreService memberStoreService;
    @Autowired
    private MemberStoreLockUtils memberStoreLockUtils;

    @Value("${wallet_service_base_url}")
    private String walletServiceUrl;
    @Value("${wallet_exdf_coin}")
    private String walletExdfCoin;
    @Value("${wallet_exdf_secret}")
    private String walletExdfSecret;
    @Value("${wallet_fee_threshold}")
    private BigDecimal walletFeeThreshold;

    //每4分钟执行一次充值上账处理任务
    @Scheduled(cron = "0 */2 * * * ?")
    public void rechargeUSDT() {
        log.info("rechargeUSDT 充值上账记录 --- start");
        List<Integer> types = WalletEnums.getRechargeTypes();
        List<RwRecord> unRechargeList = rwRecordService.listNotRechargeRecord(CoinsEnum.USDT, types);

        List<String> addrList = new ArrayList<>();
        List<RwRecord> updateRechargeList = unRechargeList.stream().map(item -> {
            log.info("新的充值记录，钱包类型 {}",WalletEnums.Type.valueOf(item.getAddrType()).getName());
            MemberStore memberStore = memberStoreService.getMemberStore(item.getMemberId(), item.getCoinsName());
            boolean lock = memberStoreLockUtils.lock(memberStore.getMemberId(), memberStore.getId());
            if (!lock) {
                return null;
            }
            try {
                MemberStoreChange memberStoreChange = MemberStoreChange.builder()
                        .memberId(item.getMemberId())
                        .coinsId(item.getCoinsId())
                        .coinsName(item.getCoinsName())
                        .changeNum(item.getRwNum())
                        .jaType(MemberJAType.RECHARGE)
                        .remark(MemberJAType.RECHARGE.getMsg())
                        .orderId(item.getId())
                        .orderDetailId(null)
                        .build();
                Integer jaId = memberStoreService.changeMemberStore(memberStoreChange);
                RwRecord updatedRecord = new RwRecord();
                if (jaId > 0) {
                    updatedRecord.setId(item.getId());
                    updatedRecord.setJaId(jaId);
                    updatedRecord.setPayStatus(RwRecordEnum.PayStatus.dao_zhang.getCode());
                    if(!addrList.contains(item.getAddress()) && item.getRwNum().compareTo(walletFeeThreshold) >= 0){
                        //大于设置的阈值才给手续费，不然浪费了
                        addrList.add(item.getAddress());
                    }
                }
                return updatedRecord;
            } finally {
                memberStoreLockUtils.unlock(memberStore.getMemberId(), memberStore.getId());
            }
        }).filter(item -> !ObjectUtils.isEmpty(item)).collect(Collectors.toList());
        if (ObjectUtils.isEmpty(updateRechargeList)) {
            log.info("rechargeUSDT 充值上账记录 0 --- end");
            return;
        }
        rwRecordService.updateBatchById(updateRechargeList);
        log.info("rechargeUSDT 充值上账记录 {} --- end", updateRechargeList.size());
        addressAddFee(addrList);
    }


    /**
     * 给充币的地址补充手续费
     * @param addrs
     */
    private void addressAddFee(List addrs){
        try{
            if(addrs.size() > 0){
                //调用 wallet 钱包自动给充值的地址补充eth手续费
                String tos = StringUtils.join(addrs,",");
                Map<String, Object> conversionParam = new HashMap<>();
                conversionParam.put("from", "coinbase");//此参数仅仅是为了配合目标接口的notblank，并无用
                conversionParam.put("coin", "ETH");
                conversionParam.put("secret", "s02ia7");
                conversionParam.put("to", tos);
                String params = new ObjectMapper().writeValueAsString(conversionParam);
                log.info("充值手续费执行地址{}", tos);
                String result = HttpUtil.post(walletServiceUrl+"/eth/fee", params);
                log.info("充值上账处理地址是否有手续费{}", result);
            }
        }catch (Exception e){
            log.info("充值上账手续费补充失败{}",e.getMessage());
        }
    }

}
